#!/usr/bin/perl -w

BEGIN {
	if(exists($ENV{TRUECL_LIBS})) {
		push @INC,$ENV{TRUECL_LIBS};
	}
	if(exists($ENV{TRUECL_CODE})) {
		push @INC,"$ENV{TRUECL_CODE}/lib";
	}
}

use strict;
use cldb;
use Getopt::Long;
use File::Basename;

$::_PRG=basename($0);

%::records=(
	);

%::tables=(
	"known_net_connections" =>
		"CREATE TABLE known_net_connections(
			ipaddr	VARCHAR(50) PRIMARY KEY,
			timeout	VARCHAR(6),
			attributes VARCHAR(200)
		);",
	"globals"	=>
		"CREATE TABLE globals(
			var VARCHAR(50) PRIMARY KEY,
			value VARCHAR(200)
		);",
	"custom_app_probes" =>
		"CREATE TABLE custom_app_probes(
			name VARCHAR(50) PRIMARY KEY,
			script VARCHAR(2048),
			update_time INTEGER
		);",
	"ports"	=> 
		"CREATE TABLE ports(
			number INTEGER PRIMARY KEY,
			type VARCHAR(10),
			detail VARCHAR(30)
		);",
	"nodes" => 
		"CREATE TABLE nodes(
			name VARCHAR(50) PRIMARY KEY,
			release VARCHAR(20),
			lha_release VARCHAR(20),
			ips VARCHAR(50)
		);",
	"application_routes" => 
		"CREATE TABLE application_routes(
			label VARCHAR(50),
			appname VARCHAR(50),
			ipaddr VARCHAR(30),
			iptype INTEGER,
			timeout CHAR(6),
			maxfails INTEGER,
			resettime INTEGER,
			severity CHAR(10),
			comments CHAR(80)
		);",
	"topology" => 
		"CREATE TABLE topology(
			name VARCHAR(50) PRIMARY KEY,
			lcards VARCHAR(200),
			pcards VARCHAR(200),
			type VARCHAR(200),
			attributes VARCHAR(200)
		);",
	"applications" => 
		"CREATE TABLE applications(
			name		VARCHAR(50),
			prefnode	VARCHAR(20),
			nodes		VHARCHAR(255),
			consistency	VARCHAR(10),
			startscript	VARCHAR(255),
			stopscript	VARCHAR(255),
			starttimeout	INTEGER,
			stoptimeout	INTEGER,
			storage		VARCHAR(40),
			vgs		VARCHAR(255),
			changetime      INTEGER,
			validated	CHAR(1)
		);",
	"cluster_events" =>
		"CREATE TABLE cluster_events(
			name		VARCHAR(30) PRIMARY KEY,
			event		VARCHAR(20),
			text		VARCHAR(80),
			type		CHAR(10),
			send_host	VARCHAR(30),
			send_port	INTEGER,
			send_email	VARCHAR(255),
			send_file	VARCHAR(255),
			send_cmd	VARCHAR(255)
		);",
	"application_ips" =>
		"CREATE TABLE application_ips(
			name		VARCHAR(50),
			network		VARCHAR(50),
			ips		VARCHAR(200),
			netmask		VARCHAR(30),
			broadcast	VARCHAR(30),
			version		INTEGER,
			topology	VARCHAR(50)
		);",
	"application_fs" =>
		"CREATE TABLE application_fs(
			name		VARCHAR(50),
			mountpnt	VARCHAR(255),
			options		VARCHAR(50),
			fstype		VARCHAR(10),
			vg		VARCHAR(30),
			lv		VARCHAR(30),
			size		INTEGER
		);",
	"locks" =>
		"CREATE TABLE locks(
			name		VARCHAR(20),
			type		VARCHAR(20),
			desc		VARCHAR(200),
			maxtime		INTEGER,
			maxkeepers	INTEGER
		);",
	"storage_shared" =>
		"CREATE TABLE storage_shared(
			name		VARCHAR(50),
			vglv		VARCHAR(50),
			vischeck	VARCHAR(200)
		);",
	"storage_nfs" => 
		"CREATE TABLE storage_nfs(
			name		VARCHAR(50),
			vglv 		VARCHAR(50),
			vischeck 	VARCHAR(200)
		);",
	"event_monitor" =>
		"CREATE TABLE event_monitor(
			type		CHAR(1),
			name		VARCHAR(20),
			appname		VARCHAR(20),
			xml		VARCHAR(2048),
			update_time	INTEGER
		);",
	"storage_drbd1" =>
		"CREATE TABLE storage_drbd1(
			devnum		INTEGER,
			appname		VARCHAR(50),
			devport		VARCHAR(20),
			vglv		VARCHAR(50),
			topology	VARCHAR(50),
			syncrate	INTEGER,
			vischeck	VARCHAR(200),
			synched		CHAR(1),
			validhost	VARCHAR(20)
		);",
	"storage_drbd82" =>
		"CREATE TABLE storage_drbd82(
			devnum		INTEGER,
			appname		VARCHAR(50),
			devport		VARCHAR(20),
			vglv		VARCHAR(50),
			topology	VARCHAR(50),
			vischeck	VARCHAR(200),
			syncrate	INTEGER,
			auth_crc	VARCHAR(20),
			data_crc	VARCHAR(20),
			synched		CHAR(1),
			validhost	VARCHAR(20)
		);",
	"diskhb" =>
		"CREATE TABLE diskhb(
			hbkey		VARCHAR(50),
			name		VARCHAR(30),
			node		VARCHAR(50),
			devpath		VARCHAR(100),
			blksize		INTEGER,
			read_offset	INTEGER,
			write_offset	INTEGER,
			update_time	INTEGER,
			validated	INTEGER
		);",
);


sub usage {
	print "
Usage: $::_PRG [--dbfile S] [--force]

The $::_PRG utility is used to create an initial configuration
database file for linuxha.net v2. At present it supports the 
following arguments:

--dbfile	The name of the database file to create - it
		must be specified or the command will abort.
--force         Allowed to run when the database exists and
                will only create tables that do not currently
		exist.

Currently it will generate the following tables:

";
	print "  * $_\n" for (sort(keys %::tables));
	print "\n";
	exit 1;
}

$::ARG_dbfile=undef;
$::ARG_force=0;

if(!GetOptions(
	"dbfile=s"	=> \$::ARG_dbfile,
	"force"		=> \$::ARG_force,
)) {
	usage;
}

if(!defined($::ARG_dbfile)) {
	usage;
}

if(-f $::ARG_dbfile && ! $::ARG_force) {
	print STDERR "Error: File $::ARG_dbfile already exists - not overwriting.\n";
	exit 1;
}

$::DBH = new cldb($::ARG_dbfile);
if(!defined($::DBH)) {
	($::rc,$::str)=cldb::error;
	print STDERR "Error: $::str [rc=$::rc]\n";
	exit 1;
}

for $::table (sort(keys %::tables)) {
	$::DBH->do($::tables{$::table});
	($::cc,$::rc)=$::DBH->error;
	if(defined($::rc)) {
		if($::rc =~ /already exists/) {
			print "Log  : Table \"$::table\" already exists.\n";
		} else {
			print STDERR "Error: Failed to create table $::table - $::rc:\n";
		}
	} else {
		print "Log  : Table \"$::table\" created successfully.\n";
	}
}

#########################################################################
# Once the tables have been created add any necessary base records.	#
#########################################################################

for $::rectype (sort(keys(%::records))) {
	for $::crec (@{$::records{$::rectype}}) {
		$::cmd="INSERT INTO $::rectype VALUES(";
		$::cmd.="'$_'," foreach(@$::crec);
		$::cmd =~ s/,$//;
		$::cmd.=");";
		$::DBH->do($::cmd);
		($::cc,$::rc)=$::DBH->error;
		if(defined($::rc)) {
			print "Error: Unable to insert record into $::rectype:\n";
			print "Error: $::rc\n";
			exit 1;
		}
	}
}

$::DBH->disconnect;

exit;
